// 确保在Windows平台下包含必要的库文件
#ifdef _WIN32
#pragma comment(lib, "ws2_32.lib") // 链接Windows Socket库(ws2_32.lib),提供网络编程功能
#endif

// 包含必要的头文件
#include <winsock2.h> // Windows套接字编程API
#include <stdio.h>    // 标准输入输出函数
#include <string.h>   // 字符串处理函数
#include <process.h>  // 线程相关函数

// 定义常量
#define BUFF_LENGTH 1024   // 消息缓冲区大小(字节)
#define USERNAME_LENGTH 32 // 用户名最大长度

// 定义用于接收消息的线程函数
// 参数arg: 指向客户端套接字的指针
unsigned __stdcall ReceiveMessages(void *arg)
{
    SOCKET sock = *(SOCKET *)arg;
    char buffer[BUFF_LENGTH]; // 消息缓冲区
    int recv_len;             // 接收到的消息长度

    // 持续接收服务器发来的消息
    while ((recv_len = recv(sock, buffer, BUFF_LENGTH - 1, 0)) > 0)
    {
        buffer[recv_len] = '\0'; // 确保字符串正确终止
        printf("%s", buffer);    // 打印接收到的消息
    }

    return 0;
}

int main()
{
    // 初始化Windows套接字环境
    WSADATA wsa_data;
    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
    {
        printf("WSAStartup failed\n");
        return 1;
    }

    // 创建TCP套接字
    SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (client_socket == INVALID_SOCKET)
    {
        printf("Socket creation failed\n");
        WSACleanup();
        return 1;
    }

    // 配置服务器地址结构
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;   // 使用IPv4地址族
    server_addr.sin_port = htons(8080); // 设置服务器端口为8080

    // 获取用户输入的服务器IP地址
    char server_ip[16];
    printf("Enter server IP address: ");
    scanf("%s", server_ip);
    getchar(); // 清除输入缓冲区中的换行符

    server_addr.sin_addr.s_addr = inet_addr(server_ip); // 设置服务器IP地址

    // 连接到服务器
    if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
    {
        printf("Connection failed\n");
        closesocket(client_socket);
        WSACleanup();
        return 1;
    }

    printf("Connected to server\n");

    // 接收并显示服务器发送的用户名提示信息
    char buffer[BUFF_LENGTH];
    int recv_len = recv(client_socket, buffer, BUFF_LENGTH - 1, 0);
    buffer[recv_len] = '\0';
    printf("%s", buffer);

    // 获取用户输入的用户名
    char username[USERNAME_LENGTH];
    fgets(username, USERNAME_LENGTH, stdin);
    username[strcspn(username, "\n")] = 0; // 移除换行符

    // 将用户名发送给服务器
    send(client_socket, username, strlen(username), 0);

    // 创建接收消息的线程
    _beginthreadex(NULL, 0, ReceiveMessages, &client_socket, 0, NULL);

    // 主循环:处理用户输入的消息
    char message[BUFF_LENGTH];
    while (1)
    {
        fgets(message, BUFF_LENGTH, stdin); // 读取用户输入的消息

        // 检查是否输入了退出命令
        if (strcmp(message, "quit\n") == 0)
        {
            break;
        }

        // 发送消息到服务器
        if (send(client_socket, message, strlen(message), 0) == SOCKET_ERROR)
        {
            printf("Send failed\n");
            break;
        }
    }

    // 清理资源
    closesocket(client_socket); // 关闭客户端套接字
    WSACleanup();               // 清理Windows套接字环境
    return 0;
}